#include "ContactsManager.h"
#include "DatabaseManager.h"
#include "DatabaseManagerException.h"
#include "KeyManager.h"
#include "Exception.h"
#include "SymmetricKeyInfo.h"

#include <QDebug>
#include <assert.h>

using namespace kryptos::database;
using namespace kryptos::entities;
using namespace kryptos::util;

namespace kryptos { namespace cryptography {

ContactsManager::ContactsManager()
{
    try
    {
        KeyManager::instance();
        DatabaseManager::manager().openGroups();

        if (!DatabaseManager::manager().hasGroup("default"))
        {
            m_defaultGroup = Group("default", Group::RSA);
            DatabaseManager::manager().addGroup(m_defaultGroup);
        }
        else
        {
            m_defaultGroup = DatabaseManager::manager().findGroup("default");
        }
    }
    catch (kryptos::util::Exception &e)
    {
        qDebug() << QString(e.what());
    }
}

ContactsManager::~ContactsManager()
{
}

ContactsManager& ContactsManager::manager()
{
    static ContactsManager instance;
    return instance;
}

void ContactsManager::addContactWithoutGroup(const Contact& contact)
{
    try
    {
        DatabaseManager::manager().addContactToGroup(contact, m_defaultGroup);
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << QString(e.what());
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }
}

void ContactsManager::addContactToGroup(const Contact& contact, const Group& group)
{
    assert(false);
}

void ContactsManager::addGroup(const Group& group)
{
    try
    {
        DatabaseManager::manager().addGroup(group);
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << e.what();
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }
}

ContactList ContactsManager::allContacts()
{
    ContactList list;
    KeyInfoList infoList;
    try
    {
        infoList = DatabaseManager::manager().allKeys();
        foreach (const KeyInfo& info, infoList)
        {
            SymmetricKeyInfoList symkeylist = DatabaseManager::manager().getSymmetricKeysAssignedToKeyID(info.keyid());
            list.push_back(Contact(info, symkeylist));
        }
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << e.what();
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }

    return list;
}

GroupList ContactsManager::allGroups()
{
    GroupList list;

    try
    {
        list = DatabaseManager::manager().allGroups();
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << e.what();
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }

    return list;
}

Group ContactsManager::groupByName(const std::string& name)
{
    Group group;
    try
    {
        group = DatabaseManager::manager().findGroup(name);
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << e.what();
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }

    return group;
}

SymmetricKeyInfoList ContactsManager::allSymmetricKeys()
{
    SymmetricKeyInfoList list;
    try
    {
        list = DatabaseManager::manager().allSymmetricKeys();
    }
    catch (DatabaseManagerException &e)
    {
        qDebug() << e.what();
        //throw KeyManagerException(KeyManagerException::LIST_KEY_ERROR, "Error listing all keys");
    }

    return list;
}

}}
